/*!
 * koa-parameter - index.js
 * Copyright(c) 2014 dead_horse <dead_horse@qq.com>
 * MIT Licensed
 */

'use strict';
/**
 * Module dependencies.
 */
import * as Koa from 'koa'
import Parameter from 'parameter';
import type { ParameterTranslateFunction } from 'parameter'
const ERR_CODE = "INVALID_PARAM"
/**
 * Makes the respond middleware. 
 * @return {Function}
 */
function init(translate?: ParameterTranslateFunction): Koa.Middleware {
    let parameter: Parameter;

    if (typeof translate === 'function') {
        parameter = new Parameter({
            translate
        })
    } else {
        parameter = new Parameter()
    }


    function verifyParams(rules: Parameter.ParameterRules, params: Record<string, any>) {
        if (!rules) {
            return;
        }
        if (!params) {
            params = ['GET', 'HEAD'].includes(this.method.toUpperCase())
                ? this.request.query
                : this.request.body;

            // copy
            params = Object.assign({}, params, this.params);
        }
        const errors = parameter.validate(rules, params);
        if (errors) {
            this.throw(422, 'Validation Failed', {
                code: ERR_CODE,
                errors: errors,
                params: params
            });
        }

    };

    async function middleware(ctx: Koa.Context, next: Koa.Next) {

        try {
            ctx.verifyParams = verifyParams.bind(ctx)
            await next()
        } catch (err) {
            let errMsg = err.errors?.map(val => `${val.code}->${val.field}`).join(";")
            if (err.code === ERR_CODE) {
                ctx.body = {
                    c: "422",
                    m: errMsg,
                    d: err.params
                };
            } else {
                throw err
            }
        }
    }
    return middleware;
}

export default init;